home *** CD-ROM | disk | FTP | other *** search
/ Super PC 31 / Super PC 31 (Shareware).iso / spc / inter / speakf / fuente / face.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  10.2 KB  |  365 lines

  1. /*
  2.  
  3.                 Show Your Face
  4.                 
  5. */
  6.  
  7. #include "netfone.h"
  8.  
  9. char faceFileName[MAX_PATH] = "";        // Face image file name
  10. int faceShow = TRUE;                    // Show faces ?
  11.  
  12. HFILE faceFile = HFILE_ERROR;             // Face image file handle
  13.  
  14. //    CLOSEFACEFILE  --  Close face file (if open)
  15.  
  16. void closeFaceFile(void)
  17. {
  18.     if (faceFile != HFILE_ERROR) {
  19.         _lclose(faceFile);
  20.         faceFile = HFILE_ERROR;
  21.     } 
  22. }
  23.  
  24. /*    OPENFACEFILE  --  Open face file and validate it's
  25.                       in a compatible format.  */
  26.  
  27. int openFaceFile(HWND hwnd)
  28. {
  29.     closeFaceFile();
  30.     if (faceFileName[0] != 0) {
  31.         faceFile = _lopen(faceFileName, READ);
  32.         if (faceFile == HFILE_ERROR) {
  33.             MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(65), (LPSTR) faceFileName);
  34.         } else {
  35.             BITMAPFILEHEADER bfh;
  36.             BITMAPINFOHEADER bmi;
  37.  
  38.             _lread(faceFile, &bfh, sizeof bfh);
  39.             if (_fstrncmp((char *) &bfh, "BM", 2) == 0) { 
  40.                 _lread(faceFile, &bmi, sizeof(BITMAPINFOHEADER));
  41.                 if (bmi.biBitCount == 8 && bmi.biCompression == BI_RGB) {
  42.                     return TRUE;
  43.                 }
  44.             }
  45.             MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(66), (LPSTR) faceFileName);
  46.             closeFaceFile();
  47.         }
  48.         return FALSE;    
  49.     }
  50.     return TRUE;
  51. }
  52.  
  53. /*    PROCESSFACEREQUEST  --  Process a face request packet and place
  54.                             the reply in the same packet.  */
  55.                             
  56. void processFaceRequest(soundbuf *d)
  57. {
  58.     long l;
  59.  
  60.     // Request for face data
  61.  
  62.     if (faceFile != HFILE_ERROR) {
  63.         _lseek(faceFile, d->buffer.buffer_len, 0);
  64.         *((long *) d->buffer.buffer_val) = htonl(d->buffer.buffer_len);
  65.         l = _lread(faceFile, d->buffer.buffer_val + sizeof(long),
  66.                 512 - (sizeof(long) + (sizeof(soundbuf) - BUFL)));
  67.         d->compression = fFaceData | faceReply;
  68.         l += sizeof(long);
  69.     } else {
  70.         // No face file.  Shut down requestor.
  71.         d->compression = fFaceData | faceLess;
  72.         l = 0;
  73.     }
  74. #ifdef TRACE_FACE    
  75.     {
  76.         char s[132];
  77.         
  78.         wsprintf(s, "Face data request for %ld, returned %ld\r\n",
  79.             ntohl(*((long *) d->buffer.buffer_val)), l);
  80.         OutputDebugString(s); 
  81.     }
  82. #endif    
  83.     d->buffer.buffer_len = l;
  84. }                            
  85.  
  86. //    FACEDLGPROC  --  Face dialogue procedure
  87.  
  88. BOOL CALLBACK faceDlgProc(HWND hwnd, UINT nMessage,
  89.                             WPARAM wParam, LPARAM lParam)
  90. {
  91.     switch (nMessage) {
  92.         case WM_INITDIALOG:
  93.             SetDlgItemText(hwnd, IDC_FA_FILENAME, faceFileName);
  94.             CheckDlgButton(hwnd, IDC_FA_SHOW, faceShow); 
  95.             return TRUE;
  96.             
  97.         case WM_CLOSE:
  98.             DestroyWindow(hwnd);
  99.             return TRUE;
  100.  
  101.         case WM_COMMAND:
  102.             switch ((int) wParam) {
  103.                 case IDC_FA_CLEAR:
  104.                     SetDlgItemText(hwnd, IDC_FA_FILENAME, "");
  105.                     break;
  106.             
  107.                 case IDC_FA_BROWSE:
  108.                      {
  109.                          OPENFILENAME ofn;
  110.                          char szString[MAX_PATH];
  111.             
  112.                         memset(&ofn, 0, sizeof(ofn));
  113.                         ofn.lStructSize = sizeof(OPENFILENAME);
  114.                         ofn.hwndOwner = hwnd;
  115.                         ofn.lpstrFilter = rfilter(IDS_T_FACE_FILE_FILTER);
  116.                         ofn.lpstrCustomFilter = NULL;
  117.                         strcpy(szString, faceFileName);
  118.                         ofn.lpstrFile = (LPSTR) szString;
  119.                         ofn.nMaxFile = sizeof(szString);
  120.                         ofn.lpstrInitialDir = NULL;
  121.                         ofn.lpstrTitle = rstring(IDS_T_FACE_OPEN_TITLE);
  122.                         ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_SHOWHELP;
  123.                         fileHelpKey = rstring(IDS_HELP_FACE);
  124.                         if (GetOpenFileName((LPOPENFILENAME) &ofn)) {
  125.                             SetDlgItemText(hwnd, IDC_FA_FILENAME, szString);
  126.                         }
  127.                     }
  128.                     break;
  129.             
  130.                 case IDOK:
  131.                     {
  132.                         char sff[MAX_PATH];
  133.                         
  134.                         _fstrcpy(sff, faceFileName);
  135.                         GetDlgItemText(hwnd, IDC_FA_FILENAME,
  136.                                             faceFileName, sizeof faceFileName);
  137.                         if (!openFaceFile(hwnd)) {
  138.                             /*    Don't let user exit until a valid (or no)
  139.                                 face file is specified.  */
  140.                             _fstrcpy(faceFileName, sff);
  141.                             break;
  142.                         }
  143.                         faceShow = IsDlgButtonChecked(hwnd, IDC_FA_SHOW);
  144.                         EndDialog(hwnd, TRUE);
  145.                     }
  146.                     break;
  147.  
  148.                 case IDCANCEL:
  149.                     EndDialog(hwnd, FALSE);
  150.                     break;
  151.                     
  152.                 case ID_HELP:
  153.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  154.                                 ((DWORD) (Lrstring(IDS_HELP_FACE))));
  155.                     holped = TRUE;
  156.                     break;
  157.             }
  158.             return FALSE;
  159.             
  160.         default:
  161.             if (nMessage == fileOpenHelpButton && fileHelpKey != NULL) {
  162.                 WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  163.                             ((DWORD) (LPSTR) fileHelpKey));
  164.                 holped = TRUE;
  165.             }
  166.             break;            
  167.     }
  168.     return FALSE;
  169. }
  170.  
  171. //    FACEDIALOGUE  --  Face configuration dialogue
  172.  
  173. int faceDialogue(HWND hWndParent)
  174. {
  175.     FARPROC pfn;
  176.     int result;
  177.  
  178.     pfn = MakeProcInstance((FARPROC) faceDlgProc, hInst);
  179.     result = DialogBox(hInst, MAKEINTRESOURCE(IDD_FACE), hWndParent, (DLGPROC) pfn);
  180.     FreeProcInstance(pfn);
  181.     return result;
  182. }
  183.  
  184. /*    PROCESSFACEDATA  --  Process a buffer-full of face image data
  185.                          received for a connection.  */
  186.                          
  187. void processFaceData(HWND hwnd, LPCLIENT_DATA c, soundbuf *d)
  188. {
  189.     if (d->compression & faceReply) {
  190.  
  191.         // Face data packet received from remote server
  192.         
  193.         if (d->buffer.buffer_len > sizeof(long)) {
  194.             long lp =  ntohl(*((long *) d->buffer.buffer_val));
  195.             BITMAPFILEHEADER FAR *bfh;
  196.  
  197.             if (lp == c->face_address) {
  198.                 if (lp == 0) {
  199.                     
  200.                     if (c->face_bmp != NULL) {
  201.                         GlobalFreePtr(c->face_bmp);
  202.                     }
  203.                     c->face_bmp = NULL;
  204.                     bfh = (BITMAPFILEHEADER *) (d->buffer.buffer_val + sizeof(long));
  205.                     if (_fstrncmp((LPSTR) &bfh->bfType, "BM", 2) != 0) {
  206. #ifdef TRACE_FACE
  207.                         char s[132];
  208.                             
  209.                         wsprintf(s, "Face image is not a Windows bitmap file\r\n");
  210.                         OutputDebugString(s);
  211. #endif
  212.                     }
  213.                     if ((DWORD) (d->buffer.buffer_len - sizeof(long)) > bfh->bfSize) {
  214. #ifdef TRACE_FACE
  215.                         char s[132];
  216.                             
  217.                         wsprintf(s, "Bogus size %ld in face bitmap\r\n", bfh->bfSize);
  218.                         OutputDebugString(s);
  219. #endif
  220.                         c->face_stat = FSabandoned;
  221.                         return;
  222.                     }
  223.                     c->face_bmp = GlobalAllocPtr(GPTR, bfh->bfSize);
  224.                     if (c->face_bmp == NULL) { 
  225. #ifdef TRACE_FACE
  226.                         char s[132];
  227.                             
  228.                         wsprintf(s, "Cannot allocate %ld bytes for face bitmap\r\n", bfh->bfSize);
  229.                         OutputDebugString(s);
  230. #endif
  231.                         c->face_stat = FSabandoned;
  232.                         return;                        
  233.                     }
  234. #ifdef TRACE_FACE
  235.                     {
  236.                         char s[132];
  237.                             
  238.                         wsprintf(s, "Receiving %ld byte face bitmap\r\n", bfh->bfSize);
  239.                         OutputDebugString(s);
  240.                     }    
  241. #endif
  242.                     _fmemcpy(c->face_bmp, d->buffer.buffer_val + sizeof(long),
  243.                         (int) d->buffer.buffer_len - sizeof(long));
  244. #ifdef TRACE_FACE
  245. if (_fstrncmp((LPSTR) &bfh->bfType, "BM", 2) != 0) {
  246.     char s[132];
  247.                             
  248.     wsprintf(s, "Bitmap %lX wiped after address %ld\r\n", c->face_bmp, c->face_address);
  249.     OutputDebugString(s);
  250. }
  251. #endif
  252.                     c->face_address += d->buffer.buffer_len - sizeof(long);
  253.                     c->face_stat = FSreply;
  254.                     c->face_retry = 0;                    
  255.                     return;
  256.                 }
  257.                 bfh = (BITMAPFILEHEADER FAR *) c->face_bmp;
  258.                 
  259.                 if ((DWORD) (c->face_address + (d->buffer.buffer_len - sizeof(long))) >
  260.                     bfh->bfSize) {
  261. #ifdef TRACE_FACE
  262.                     char s[132];
  263.                             
  264.                     wsprintf(s, "Address %ld plus buffer length %ld overflows %ld byte bitmap\r\n",
  265.                         c->face_address, d->buffer.buffer_len - sizeof(long), bfh->bfSize);
  266.                     OutputDebugString(s);
  267. #endif
  268.                     GlobalFreePtr(c->face_bmp);
  269.                     c->face_bmp = NULL;
  270.                     c->face_stat = FSabandoned;
  271.                     return;                        
  272.                 } 
  273. #ifdef TRACE_FACE
  274.                 {     char s[132];
  275.                     
  276.                     wsprintf(s, "Storing %ld bytes at %ld in face bitmap\r\n",
  277.                         d->buffer.buffer_len - sizeof(long), lp);
  278.                     OutputDebugString(s);
  279.                 }
  280. #endif
  281.                 _fmemcpy(c->face_bmp + c->face_address,
  282.                     d->buffer.buffer_val + sizeof(long),
  283.                     (int) (d->buffer.buffer_len - sizeof(long)));
  284. #ifdef TRACE_FACE
  285. //    Check for wipeout of bitmap when connection created from other end
  286. if (_fstrncmp((LPSTR) &bfh->bfType, "BM", 2) != 0) {
  287.     char s[132];
  288.                             
  289.     wsprintf(s, "Bitmap %lX wiped after address %ld\r\n", c->face_bmp, c->face_address);
  290.     OutputDebugString(s);
  291. }
  292. #endif
  293.                 c->face_address += d->buffer.buffer_len - sizeof(long);
  294.                 /* Timeout will make next request after the
  295.                    configured interval. */
  296.                 c->face_stat = FSreply;
  297.                 c->face_retry = 0;
  298.             } else {
  299. #ifdef TRACE_FACE
  300.                 {    char s[132];
  301.                     
  302.                     wsprintf(s, "Discarded %ld bytes for %ld in face bitmap, expected data for %ld\r\n",
  303.                         d->buffer.buffer_len - sizeof(long),
  304.                         lp, c->face_address);
  305.                     OutputDebugString(s);
  306.                 }
  307. #endif                    
  308.             }
  309.         } else {
  310.             BITMAPINFOHEADER FAR *bmi;
  311.             int bx, by;
  312.             RECT cr, wr;
  313.  
  314. #ifdef TRACE_FACE
  315.             {    char s[132];
  316.                     
  317.                 wsprintf(s, "Face bitmap complete\r\n");
  318.                 OutputDebugString(s);
  319.             }
  320. #endif
  321.             c->face_stat = FScomplete;
  322.             
  323.             //    Resize window so that client area fits bitmap
  324.                         
  325.             GetWindowRect(hwnd, &wr);
  326.             GetClientRect(hwnd, &cr);
  327.                         
  328.             bmi = (BITMAPINFOHEADER FAR *) (c->face_bmp + sizeof(BITMAPFILEHEADER));
  329.             bx = (int) bmi->biWidth;
  330.             by = (int) bmi->biHeight;
  331.             if (bx != cr.right || by != cr.bottom) {
  332.                 int bw = bx + ((wr.right - wr.left) - cr.right),
  333.                     bh = by + ((wr.bottom - wr.top) - cr.bottom);
  334.                                 
  335.                 SetWindowPos(hwnd, HWND_TOP,
  336.                     0, 0, bw, bh, SWP_NOMOVE | SWP_NOZORDER);    
  337.                 GetClientRect(hwnd, &cr);
  338. #ifdef TRACE_FACE 
  339.                 {    char s[132];
  340.                             
  341.                     wsprintf(s, "Resizing connection window to %dx%d (W=%dx%d)\r\n",
  342.                         bx, by, bw, bh);    
  343.                     OutputDebugString("Resizing connection window.\r\n");
  344.                 }
  345. #endif                                                        
  346.             }
  347.             InvalidateRect(hwnd, NULL, FALSE);
  348.         }        
  349.     } else if (d->compression & faceLess) {
  350.         if (c->face_bmp != NULL) {
  351.             GlobalFreePtr(c->face_bmp);
  352.             c->face_bmp = NULL;
  353.         }        
  354.         c->face_stat = FSabandoned;
  355. #ifdef TRACE_FACE
  356.         {    char s[MAX_HOST + 80];
  357.                     
  358.             wsprintf(s, "No face image available from %s\r\n", c->szHost);
  359.             OutputDebugString(s);
  360.         }
  361. #endif                    
  362.     }
  363. }                         
  364.                     
  365.